﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace RPG
{
    //Simple Button with Events
    public class CGUIButton : CGUIObject
    {
        //Private
        private Texture2D buttonTexture;
        private SpriteFont buttonTextFont;
        private bool displayButtonText;
        private string buttonText;
        private Color buttonTextColor;
        private Vector2 buttonTextOrigin;
        private CGUIObject.TextAlign buttonTextAlign;

        //Event Handler
        public ButtonEventHandler Event_OnLeftPress;
        public ButtonEventHandler Event_OnRightPress;
        public ButtonEventHandler Event_OnLeftRelease;
        public ButtonEventHandler Event_OnRightRelease;

        //Constructor
        //Creates a new GUI Button. The position should be in coordinates relative to the parent-window.
        public CGUIButton(Texture2D _buttonTexture, Vector2 _buttonPosition)
        {
            //Set Aligned Properties
            buttonTexture = _buttonTexture;
            position = _buttonPosition;
            size = new Vector2(buttonTexture.Width, buttonTexture.Height);
            Vector3 buttonBoundingBoxMin = new Vector3(position, 0);
            Vector3 buttonBoundingBoxMax = buttonBoundingBoxMin + new Vector3(size, 0);
            boundingBox = new BoundingBox(buttonBoundingBoxMin, buttonBoundingBoxMax);
            //Set Default Properties
            SetTextAlign(TextAlign.TOPLEFT);
            displayButtonText = false;
            buttonTextColor = Color.White;
        }

        //Called on Draw
        public override void Draw(SpriteBatch spriteBatch)
        {
            if (parentWindow != null)
            {
                spriteBatch.Draw(buttonTexture, position + parentWindow.windowPosition, Color.White);
                if (displayButtonText)
                {
                    spriteBatch.DrawString(buttonTextFont, buttonText, position + parentWindow.windowPosition, buttonTextColor,
                        0f, buttonTextOrigin, 1f, SpriteEffects.None, 0f);
                }
            }
            else
            {
                spriteBatch.Draw(buttonTexture, position, Color.White);
                if (displayButtonText)
                {
                    spriteBatch.DrawString(buttonTextFont, buttonText, position, buttonTextColor,
                        0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
                }
            }
        }

        public override void Update(GameTime gameTime, MouseState oldMouseState, MouseState newMouseState)
        {

            //Check if the Left Click event is not null
            if (Event_OnLeftPress != null)
            {
                //Check if the left mouse button was clicked
                if (newMouseState.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Released)
                {
                    //Checks if Mouse intersects the button
                    Vector3 mousePos = new Vector3(newMouseState.X, newMouseState.Y, 0);
                    BoundingBox mouseBoundingBox = new BoundingBox(mousePos, mousePos);
                    if (mouseBoundingBox.Intersects(boundingBox))
                    {
                        //On intersection call OnLeftClick
                        Event_OnLeftPress.Invoke(this);
                    }
                }
            }
            //Check if the Right Click event is not null
            if (Event_OnRightPress != null)
            {
                //Same as above with Right Click
                if (newMouseState.RightButton == ButtonState.Pressed && oldMouseState.RightButton == ButtonState.Released)
                {
                    Vector3 mousePos = new Vector3(newMouseState.X, newMouseState.Y, 0);
                    BoundingBox mouseBoundingBox = new BoundingBox(mousePos, mousePos);
                    if (mouseBoundingBox.Intersects(boundingBox))
                    {
                        Event_OnRightPress.Invoke(this);
                    }
                }
            }
            //Check if the Left Release event is not null
            if (Event_OnLeftRelease != null)
            {
                //Check if the Left Mouse Button was released
                if (newMouseState.LeftButton == ButtonState.Released && oldMouseState.LeftButton == ButtonState.Pressed)
                {
                    Vector3 mousePos = new Vector3(newMouseState.X, newMouseState.Y, 0);
                    BoundingBox mouseBoundingBox = new BoundingBox(mousePos, mousePos);
                    if (mouseBoundingBox.Intersects(boundingBox))
                    {
                        Event_OnLeftRelease.Invoke(this);
                    }
                }
            }
            //Check if the Right Release event is not null
            if (Event_OnRightRelease != null)
            {
                //Check if the Right Mouse Button was released
                if (newMouseState.RightButton == ButtonState.Released && oldMouseState.RightButton == ButtonState.Pressed)
                {
                    Vector3 mousePos = new Vector3(newMouseState.X, newMouseState.Y, 0);
                    BoundingBox mouseBoundingBox = new BoundingBox(mousePos, mousePos);
                    if (mouseBoundingBox.Intersects(boundingBox))
                    {
                        Event_OnRightRelease.Invoke(this);
                    }
                }
            }
        }

        //Function to set the text-align, has to be called after the font / text changes
        public void SetTextAlign(CGUIObject.TextAlign where)
        {
            buttonTextAlign = where;
            switch (where)
            {
                case CGUIObject.TextAlign.TOPLEFT:
                    buttonTextOrigin = Vector2.Zero;
                    break;
                case CGUIObject.TextAlign.CENTERED:
                    buttonTextOrigin = buttonTextFont.MeasureString(buttonText) / 2 - size/2;
                    break;
                case CGUIObject.TextAlign.TOPRIGHT:
                    buttonTextOrigin = new Vector2(buttonTextFont.MeasureString(buttonText).X - size.X, 0);
                    break;
                case CGUIObject.TextAlign.BOTTOMLEFT:
                    buttonTextOrigin = new Vector2(0, buttonTextFont.MeasureString(buttonText).Y - size.Y);
                    break;
                case CGUIObject.TextAlign.BOTTOMRIGHT:
                    buttonTextOrigin = buttonTextFont.MeasureString(buttonText) - size;
                    break;
                case TextAlign.TOP:
                    buttonTextOrigin = new Vector2(buttonTextFont.MeasureString(buttonText).X / 2 - size.X / 2, 0);
                    break;
                case TextAlign.BOTTOM:
                    buttonTextOrigin = new Vector2(buttonTextFont.MeasureString(buttonText).X / 2 - size.X / 2,
                        buttonTextFont.MeasureString(buttonText).Y - size.Y);
                    break;
                case TextAlign.LEFT:
                    buttonTextOrigin = new Vector2(0, buttonTextFont.MeasureString(buttonText).Y / 2 - size.Y / 2);
                    break;
                case TextAlign.RIGHT:
                    buttonTextOrigin = new Vector2(buttonTextFont.MeasureString(buttonText).X - size.X, 
                        buttonTextFont.MeasureString(buttonText).Y / 2 - size.Y / 2);
                    break;
                default:
                    break;
            }
        }

        public void SetTexture(Texture2D whichTexture)
        {
            buttonTexture = whichTexture;
        }

        public void SetFont(SpriteFont whichFont)
        {
            buttonTextFont = whichFont;
            SetTextAlign(buttonTextAlign);
        }

        public void SetTextColor(Color whichColor)
        {
            buttonTextColor = whichColor;
        }

        public void SetText(string whichText)
        {
            buttonText = whichText;
            SetTextAlign(buttonTextAlign);
        }

        public void ShowButtonText(bool showButtonText)
        {
            displayButtonText = showButtonText;
        }
    }
}
